/**
 * @project: parallel-task
 * @package: com.ngplat.paralleltask.forkjoin
 * @filename: AbstractRecursiveWorker.java
 *
 * Copyright (c) 2018 eSunny Info. Tech Ltd. All rights reserved.
 * 
 */
package com.ngplat.paralleltask.forkjoin;

import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ngplat.paralleltask.task.TaskContext;

/**
 * @typename: AbstractRecursiveWorker
 * @brief: 实际执行业务逻辑的工作者
 * @author: KI ZCQ
 * @date: 2018年6月4日 上午10:23:57
 * @version: 1.0.0
 * @since
 * 
 */
public abstract class AbstractRecursiveWorker<T> implements RecursiveWorker<TaskContext>, Runnable {

	private static Logger logger = LoggerFactory.getLogger(AbstractRecursiveWorker.class);
	/**
	 * 执行上下文环境, 可以保存你的参数和结果
	 */
	protected TaskContext context;
	/**
	 * 任务名称
	 */
	protected String taskName;
	/**
	 * 计算资源, 遍历这个就行了~
	 */
	protected List<T> calcList;
	/**
	 * 统计任务完成情况
	 */
	protected final CountDownLatch workerComplete;

	/**
	 * 创建一个新的实例 AbstractRecursiveWorker.
	 * 
	 * @param context
	 *            计算上下文
	 * @param calcList
	 *            计算资源
	 * 
	 * @param countDownLatch
	 *            用于统计任务完成情况
	 */
	public AbstractRecursiveWorker(TaskContext context, List<T> list, CountDownLatch countDownLatch) {
		this.context = context;
		this.calcList = list;
		this.workerComplete = countDownLatch;
	}

	/**
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		// 处理业务
		work(context);
		// 通知子任务已完成
		afterExecute();
		// 打印日志
		logger.info("[{}]任务执行完成.", this.taskName);
	}

	/**
	 * @Description: 设置Context
	 * @param context
	 */
	public void setContext(TaskContext context) {
		this.context = context;
	}
	
	/**
	 * @Description: 通知任务完成
	 */
	public void afterExecute() {
		workerComplete.countDown();
	}

	/**
	 * taskName
	 *
	 * @return  the taskName
	 * @since   1.0.0
	*/
	public String getTaskName() {
		return taskName;
	}

	/**
	 * @param taskName the taskName to set
	 */
	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}
	
}
